package com.ruoyi.business.service;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.business.Advice;
import com.ruoyi.business.User;
import com.ruoyi.business.UserWxInfo;
import com.ruoyi.business.enums.StatusEnum;
import com.ruoyi.business.mapper.AdviceMapper;
import com.ruoyi.business.mapper.UserMapper;
import com.ruoyi.common.utils.AesException;
import com.ruoyi.common.utils.DocumentUtil;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author ：jiangguanjun
 * @description：微信相关
 * @date ：2020/7/16 21:13
 */
@Slf4j
@Component
public class WechartService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${weixin.app_id}")
    private String appId ;

    @Value("${weixin.secret}")
    private String secret ;

    @Value("${weixin.url}")
    private String url ;

    @Value("${weixin.tokenPath}")
    private String tokenPath ;

    @Autowired
    private RestTemplate restTemplate ;
    @Autowired
    private UserMapper userMapper ;

    @Autowired
    private AdviceMapper adviceMapper ;




    public String getAccessToken(){
        Object token = redisTemplate.opsForValue().get("accessToken") ;
        if(token != null){
            return token.toString() ;
        }
        String resUrl = url + tokenPath + "?grant_type=client_credential&appid="+appId+"&secret="+secret ;
        JSONObject jsonObject = restTemplate.getForObject(resUrl, JSONObject.class) ;
        log.info("access_token::::{}",jsonObject.toJSONString());
        String accessToken = jsonObject.getString("access_token") ;
        Long expiresIn = jsonObject.getLongValue("expires_in") ;
        redisTemplate.opsForValue().set("accessToken",accessToken,expiresIn-2, TimeUnit.SECONDS);
        return accessToken ;
    }

    public String process(HttpServletRequest request) throws AesException, DocumentException {
        String result = "success" ;
        // TODO 关注事件，则将用户的状态，如果用户不存在则保存该用户，如果用户不存在则保存用户，如果用户存在则查看用户是否为禁用状态，如果用户为取关状态则将用户置为正常状态
        // TODO 取消关注，如果用户取消关注则将用户的状态置为取关状态
       /* String token = "lootaa";
        String encodingAesKey = "FpKEYJDuwK92k2juU2z0sUvTmc3hB4W5wGLJEKay8oK";
        String appid = "wx276049d6a7551dca";
        WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appid);
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String msgSignature = request.getParameter("msg_signature");*/
        Document doc = DocumentUtil.getDocument(request);
        //String result2 = pc.decryptMsg(msgSignature, timestamp, nonce, doc.asXML());
        String result2 = doc.asXML() ;

        log.info("解密后明文:::{}",result2);
        Map<String, String> map = DocumentUtil.docToMap(DocumentHelper.parseText(result2));
        //这个值如果是event表示是事件推送；如果是其他字符，参照Test004
        String messageType = map.get("MsgType");
        if(Objects.equals("event", messageType)) {
            //这个是事件的具体类型
            String event = map.get("Event");

            //公众号订阅
            if(Objects.equals(event, "subscribe")) {
                log.info("进入公众号订阅");

                User userDB = userMapper.selectByOpenId(map.get("FromUserName")) ;
                int res = -1 ;
                if(userDB == null){
                    userDB = new User() ;
                    userDB.setOpenId(map.get("FromUserName"));
                    res = userMapper.insertSelective(userDB) ;
                }else if(!userDB.getStatus().equals( StatusEnum.FORBIDDEN.getCode())){
                    userDB.setStatus(StatusEnum.NOMAL.getCode());
                    res = userMapper.updateSelectiveByOpenId(userDB) ;
                }
                if(res>0){
                    result = "<xml>" + "<ToUserName><![CDATA[" + map.get("FromUserName") + "]]></ToUserName>"
                            + "<FromUserName><![CDATA[" + map.get("ToUserName") + "]]></FromUserName>" + "<CreateTime>"
                            + System.currentTimeMillis() + "</CreateTime>" + "<MsgType><![CDATA[text]]></MsgType>"
                            + "<Content><![CDATA[欢迎关注！]]></Content></xml>";

                    log.info("关注之后回复的内容：：：：{}",result);
                    return result ;
                }
                //  result = pc.encryptMsg(result, timestamp, nonce);
                return result;
            }

            //公众号订取消阅
            if(Objects.equals(event, "unsubscribe")) {
                System.out.println("取消订阅");
                String openId = map.get("FromUserName") ;
                User user = new User() ;
                user.setOpenId(openId);
                user.setStatus(StatusEnum.UNSUBSCRIBE.getCode());
                int res = userMapper.updateSelectiveByOpenId(user) ;
                return "success";
            }

            //已关注的用户扫码
            /*if(Objects.equals(event, "SCAN")) {
                //qrscene_开头
                String eventKey = map.get("EventKey");
                if(eventKey != null && eventKey.length() > 0) {
                    System.out.println("二维码参数" + eventKey.replaceFirst("qrscene_", ""));
                }
                //用来生成二维码
                String ticket = map.get("Ticket");
                if(ticket != null) {
                    String code = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket;
                    System.out.println("二维码：" + code);
                }
                return "success";
            }

            //上报地理位置事件
            if(Objects.equals(event, "LOCATION")) {
                //纬度
                String latitude = map.get("Latitude");
                //经度
                String longitude = map.get("Longitude");
                //精度，感觉没啥用
                String precision = map.get("Precision");
                System.out.println(latitude + "," + longitude + "," + precision);
                return "success";
            }

            //点击菜单事件
            if(Objects.equals(event, "CLICK")) {
                String eventKey = map.get("EventKey");  //事件 KEY 值
                String result = "<xml>" + "<ToUserName><![CDATA[" + map.get("FromUserName") + "]]></ToUserName>"
                        + "<FromUserName><![CDATA[" + map.get("ToUserName") + "]]></FromUserName>" + "<CreateTime>"
                        + System.currentTimeMillis() + "</CreateTime>" + "<MsgType><![CDATA[text]]></MsgType>"
                        + "<Content><![CDATA[" + eventKey + "]]></Content></xml>";
                result = pc.encryptMsg(result, timestamp, nonce);
                return result;
            }

            if(Objects.equals(event, "VIEW")) { //点击菜单跳转链接
                String eventKey = map.get("EventKey");  //链接地址
                System.out.println(eventKey);
                return "success";
            }*/

        }else if(messageType.equals("text")){

            Advice advice = new Advice() ;
            advice.setContent(map.get("Content"));
            String fromUserName = map.get("FromUserName") ;
            User user = userMapper.selectByOpenId(fromUserName) ;
            advice.setOpenId(fromUserName);
            if(user.getCity() != null){
                advice.setCity(user.getCity());
            }
            advice.setName(user.getNike());
            adviceMapper.insertSelective(advice) ;
        }
        return "success" ;
    }


    public UserWxInfo getWxUserInfo(String openId){
        String accessToken = getAccessToken() ;

        // 获取用户信息的URL
        String userInfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info" +
                "?access_token=" + accessToken +
                "&openid=" + openId +
                "&lang=zh_CN";

        // 发送GET请求获取用户信息
        log.info("请求地址：：：：{}",userInfoUrl);
        String userInfoStr = restTemplate.getForObject(userInfoUrl,String.class) ;
        log.info("用户基本信息：：{}",userInfoStr);
        UserWxInfo userInfoJson = JSONObject.parseObject(userInfoStr,UserWxInfo.class) ;
        return userInfoJson ;
    }
}
